package com.farm.wcp.client;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;

import com.farm.wcp.client.domain.RemoteKnow;
import com.farm.wcp.client.utils.ClientFileHttpUploads;
import com.farm.wcp.client.utils.HttpUtils;
import com.farm.wcp.client.utils.WdasJsonMap;

/**
 * 接口知识创建器接口
 * 
 * @author macpl
 *
 */
public class WcpCreaterClient {
	private Map<String, String> urls;
	private String secret;
	private String operatorLoginname;
	private String operatorPassword;
	private String baseUrl;
	private WcpClient wcpclient;
	private String version;

	/**
	 * @param wcpclient
	 * @param apiVersion 可选1：api/access接口
	 */
	public static WcpCreaterClient getAccessClient(WcpClient wcpclient) {
		WcpCreaterClient client = new WcpCreaterClient(wcpclient);
		client.version = "ACCESS";
		client.secret = wcpclient.getSecret();
		client.baseUrl = wcpclient.getBaseUrl();
		client.operatorLoginname = wcpclient.getOperatorLoginname();
		client.operatorPassword = wcpclient.getOperatorPassword();
		client.wcpclient = wcpclient;
		return client;
	}

	public WcpCreaterClient(WcpClient wcpclient) {
		super();
		this.secret = wcpclient.getSecret();
		this.baseUrl = wcpclient.getBaseUrl();
		this.operatorLoginname = wcpclient.getOperatorLoginname();
		this.operatorPassword = wcpclient.getOperatorPassword();
		this.wcpclient = wcpclient;
	}

	/**
	 * 创建一个图片文件（base64）
	 * 
	 * @param base64
	 * @param filename
	 * @return
	 */
	public WdasJsonMap addImgFileByBase64(String base64, String filename) {
		Map<String, String> para = new HashMap<String, String>();
		initBaseParas(para);
		para.put("base64", base64);
		para.put("filename", filename);
		JSONObject json = HttpUtils.httpPost(getApiUrls().get("addBase64img"), para);
		validateBackJson(getApiUrls().get("addBase64img"), json);
		WdasJsonMap wjm = new WdasJsonMap(json.toMap());
		return wjm;
	}

	/**
	 * 创建文件通过一个在服务器上存在的文件
	 * 
	 * @param serverFilePath
	 * @return
	 */
	public WdasJsonMap addFileByServerPath(String serverFilePath) {
		Map<String, String> para = new HashMap<String, String>();
		initBaseParas(para);
		para.put("filePath", serverFilePath);
		JSONObject json = HttpUtils.httpPost(getApiUrls().get("addLocalFile"), para);
		validateBackJson(getApiUrls().get("addLocalFile"), json);
		WdasJsonMap wjm = new WdasJsonMap(json.toMap());
		return wjm;
	}

	/**
	 * 创建文件，通过远程上传的方式
	 * 
	 * @param file
	 * @param localid 附件的本地唯一KEY（不会重复上传相同key的文件）
	 * @return
	 * @throws IOException
	 */
	public WdasJsonMap addFile(File file, String localid) throws IOException {
		return addFile(file, null, localid);
	}

	public WdasJsonMap addFile(File file, String filename, String localid) throws IOException {
		if(!file.exists()) {
			throw new RuntimeException("the file is not exist:"+file.getPath());
		}
		Map<String, String> para = new HashMap<String, String>();
		initBaseParas(para);
		ClientFileHttpUploads client = ClientFileHttpUploads.getInstance(getApiUrls().get("addFile"), para);
		client.setRemoteProgressUrl(getApiUrls().get("upprocess"));
		client.setRemoteFileExistUrl(getApiUrls().get("findFile"));
		client.setProgressHandle(new ClientFileHttpUploads.ProgressHandle() {
			@Override
			public void handle(int percent, long allsize, long completesize, String state) {
				if (percent % 10 == 0 || percent > 50) {
					System.out.println("完成：" + state + ":" + percent + "%");
				}
			}
		});
		if (StringUtils.isBlank(filename)) {
			filename = file.getName();
		}
		JSONObject json = client.doUpload(file, filename, localid);
		validateBackJson(getApiUrls().get("addLocalFile"), json);
		WdasJsonMap wjm = new WdasJsonMap(json.toMap());
		return wjm;
	}

	/**
	 * 创建文件，通过远程上传的方式
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public WdasJsonMap addFile(File file) throws IOException {
		return addFile(file, UUID.randomUUID().toString().replace("-", ""));
	}

	/**
	 * 通过同步id获取附件信息
	 * 
	 * @param syncid
	 * @return
	 */
	public WdasJsonMap getFile(String syncid) {
		Map<String, String> para = new HashMap<String, String>();
		initBaseParas(para);
		para.put("syncid", syncid);
		JSONObject json = HttpUtils.httpPost(getApiUrls().get("findFile"), para);
		validateBackJson(getApiUrls().get("findFile"), json);
		WdasJsonMap wjm = new WdasJsonMap(json.toMap());
		return wjm;
	}

	/**
	 * 合并全文检索的索引文件
	 * 
	 * @return
	 */
	public WdasJsonMap mergeIndex() {
		Map<String, String> para = new HashMap<String, String>();
		initBaseParas(para);
		JSONObject json = HttpUtils.httpPost(getApiUrls().get("luceneMerge"), para);
		validateBackJson(getApiUrls().get("luceneMerge"), json);
		WdasJsonMap wjm = new WdasJsonMap(json.toMap());
		return wjm;
	}

	/**
	 * 创建知识
	 * 
	 * @param remoteKnow
	 * @return
	 */
	public String creatKnow(RemoteKnow remoteKnow) {
		Map<String, String> para = new HashMap<String, String>();
		initBaseParas(para);
		para.put("title", remoteKnow.getTitle());// 知识标题 必填
		para.put("type", remoteKnow.getType());// 知识分类 必填,可以是32位的ID,或者是分类路径用“//”符号分隔，如“常见问题//异常恢复”
		para.put("text", remoteKnow.getText());// 知识正文 必填
		para.put("writetype", remoteKnow.getWritetype());// 知识编辑类型 必填：1分类,0创建人,2小组
		para.put("readtype", remoteKnow.getReadtype());// 知识阅读类型 必填：1分类,0创建人,2小组
		para.put("syncid", remoteKnow.getSyncid());// 同步ID，通过该ID来判断是否重复创建，如果已经存在该ID则进行更新操作 选填，32位字符串
		para.put("resourceurl", remoteKnow.getResourceurl());// 知识来源url 选填
		para.put("domtype", remoteKnow.getDomtype());// 知识类型 选填,不填时默认为1(1:文档知识,5:资源知识,6:引用知识)
		para.put("fileids", remoteKnow.getFileids());// 资源知识的附件id,多个用逗号(,)分隔 当domtype为2时必填
		para.put("tags", remoteKnow.getTags());// 标签 选填，多个标签间用英文逗号(,)分隔
		para.put("groupid", remoteKnow.getGroupid());// 知识小组id 选填
		para.put("imgid", remoteKnow.getImgid());// 预览图id 选填
		para.put("typefieldjson", remoteKnow.getTypefieldjson());// 分类属性
		para.put("state", remoteKnow.getState());// 状态
		JSONObject json = HttpUtils.httpPost(getApiUrls().get("creatKnow"), para);
		validateBackJson(getApiUrls().get("creatKnow"), json);
		WdasJsonMap wjm = new WdasJsonMap(json.toMap());
		return wjm.getString("ID");

	}

	/**
	 * 校驗接口執行情況
	 * 
	 * @param url
	 * 
	 * @param json
	 */
	private void validateBackJson(String url, JSONObject json) {
		String state = json.get("STATE").toString();
		if (state.equals("1")) {
			throw new RuntimeException(json.get("MESSAGE").toString() + " by " + url);
		}
	}

	/**
	 * 填充密钥和接口用户信息
	 * 
	 * @param para
	 */
	private void initBaseParas(Map<String, String> para) {
		para.put("operatorLoginname", operatorLoginname);
		para.put("operatorPassword", operatorPassword);
		para.put("secret", secret);
	}

	private Map<String, String> getApiUrls() {
		if (version != null && version.equals("ACCESS")) {
			urls = new HashMap<>();
			urls.put("addBase64img", baseUrl + "/access/img/addbase64.do");
			urls.put("addLocalFile", baseUrl + "/access/file/addlocal.do");
			urls.put("addFile", baseUrl +      "/access/file/upload.do");
			urls.put("upprocess", baseUrl +    "/access/file/process.do");
			urls.put("findFile", baseUrl +     "/access/file/info.do");
			urls.put("luceneMerge", baseUrl +  "/access/index/merge.do");
			urls.put("creatKnow", baseUrl +    "/access/know/create.do");
			return urls;
		}
		urls = new HashMap<>();
		urls.put("addBase64img", baseUrl + "/add/base64img.do");
		urls.put("addLocalFile", baseUrl + "/add/localFile.do");
		urls.put("addFile", baseUrl + "/add/upfile.do");
		urls.put("upprocess", baseUrl + "/add/upprocess.do");
		urls.put("findFile", baseUrl + "/find/syncfile.do");
		urls.put("luceneMerge", baseUrl + "/lucene/merge.do");
		urls.put("creatKnow", baseUrl + "/create/know.do");
		return urls;
	}

	public boolean isLive(boolean isThrowError) {
		try {
			@SuppressWarnings("unused")
			WdasJsonMap wjm = wcpclient.getRemoteOrgByAppid("NONE");
			return true;
		} catch (Exception e) {
			if (isThrowError) {
				throw e;
			} else {
				return false;
			}
		}
	}

	public String getSecret() {
		return secret;
	}

	public String getOperatorLoginname() {
		return operatorLoginname;
	}

	public String getOperatorPassword() {
		return operatorPassword;
	}

	public String getBaseUrl() {
		return baseUrl;
	}

}
